/*******************************************************************************
 * Copyright (c) 2007 TOPCASED. All rights reserved. This program
 * and the accompanying materials are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies this distribution, and is
 * available at http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors: Topcased contributors and others - initial API and implementation
 *******************************************************************************/
/**
 * This is a fork of the UML2Java Plug-in developed by Topcased and released under
 * the Eclipse EPL License. http://www.eclipse.org/legal/epl-v10.html
 * In accordance with the license, I have forked the UML2Java plugin and have adapted
 * it to suit the needs of a UML2QoS instrumentation code generator for PHP.
 * 
 * @author Alexandru Burdusel
 */
package org.topcased.uml2qos.utilities;

import java.util.Hashtable;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.QualifiedName;
import org.topcased.uml2qos.GenQos;

import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;

/**
 * Configuration utilities
 * @author Ariel RAMPHUL (Sopra Group - Toulouse)
 */
public class Configuration
{
    
    private static Hashtable<String,String> config = new Hashtable<String,String>();
    private static boolean initialized = false;
    private static String header;
    private static boolean parameterized = false;

    /**
     * Return the value of a key
     * @param key
     * @return the value associated to the key
     */
    public static String getStringValue(String key)
    {
        if (!initialized)
        {
            initConfig();
        }
        
        if (config.get(key) != null)
        {
            return config.get(key);
        }
        else
        {
            Log.log("Can't find specified key (key : " + key + ").");
            return "";
        }
    }
    
    /**
     * Return a boolean value if the specified key is associated to a boolean value
     * @param key
     * @return the value associated to the key
     */
    public static Boolean getBooleanValue(String key)
    {
        if (!initialized)
        { 
            initConfig();
        }
       
        if (config.get(key) != null)
        {
            if (config.get(key).compareTo("true") == 0)
            {
                return true;
            }
            if (config.get(key).compareTo("false") == 0)
            { 
                return false;
            }
            Log.log("Invalid type (boolean) for the specified key (key : " + key + ").");
            return false;
        }
        else
        {
            Log.log("Can't find specified key (key : " + key + ").");
            return false;
        }
    }
    
    /**
     * Return true if the user has selected to generate the accessors
     * @param c is an UML element
     * @return a boolean value
     */
    public static Boolean isGenAccessors(org.eclipse.uml2.uml.Classifier c)
    {
        return getBooleanValue("GenerateAccessors");
    }    
    
    /**
     * Return the header
     * @return the header
     */
    public static String getHeader()
    {
        return header;
    }
    
    /**
     * Load the default config if the program can't find any configuration info in the ressources
     */
    public static void loadDefaultConfig()
    {     
        config.clear(); 
        config.put("GenerateAuthor", "true");    
        config.put("GenerateAccessors", "true");      
        config.put("GenerateHeader", "true");  
        config.put("GenerateJavaDoc", "true");          
        config.put("SpacesInsteadOfTab", "true");    
        config.put("Author", "Your_name_here"); 
        Log.log(2,"Using default configuration. You should customize the code generation (in the properties of the model - shortcut alt+Enter)");
        initialized = true;
    }
    
    public static String getDefaultValue(String s)
    {
        if (s.compareTo("GEN_AUTHOR") == 0)
        {
            return "true";
        }
        
        if (s.compareTo("GEN_HEADER") == 0)
        {
            return "true";
        }
        
        if (s.compareTo("GEN_ACCESSORS") == 0)
        {
            return "true";
        }
        
        if (s.compareTo("GEN_JAVADOC") == 0)
        {
            return "true";
        }
        
        if (s.compareTo("USE_CHECKSTYLE") == 0)
        {
            return "true";
        }
        
        if (s.compareTo("AUTHOR_NAME") == 0)
        {
            return "Your_name_here";
        }           
        
        return "";
    }
    
    /**
     * Load the default header if the program can't find any configuration info in the ressources
     */ 
    public static void loadDefaultHeader()
    {     
        header = "/*******************************************************************************\n";
        header = header + " * Copyright (c) 2011 YourNameHere All rights reserved. This program\n";
        header = header + " * and the accompanying materials are made available under the terms of the\n";        
        header = header + " * Eclipse Public License v1.0 which accompanies this distribution, and is\n";
        header = header + " * available at http://www.eclipse.org/legal/epl-v10.html\n";      
        header = header + " *\n";    
        header = header + "*******************************************************************************/\n";        
    }
    
    /**
     * Return true if the user has selected to generate the phpdoc
     * @param c is an UML element
     * @return a boolean value
     */
    public static boolean isDocNeeded(org.eclipse.uml2.uml.Classifier c)
    {
        return Configuration.getBooleanValue("GenerateJavaDoc");
    }
    
    /**
     * Return true if the user has selected to generate the phpdoc
     * @param c is a classifier
     * @return a boolean value
     */
    public static boolean isDocNeeded(org.eclipse.uml2.uml.InterfaceRealization c)
    {
        return Configuration.getBooleanValue("GenerateJavaDoc");
    }    
    
    /**
     * Return true if the user has selected to generate the phpdoc
     * @return a boolean value
     */
    public static boolean isDocNeeded()
    {
        return Configuration.getBooleanValue("GenerateJavaDoc");
    }    
    
    /**
     * Return true if the user has selected to generate the phpdoc
     * @param c is an operation
     * @return a boolean value
     */
    public static boolean isDocNeeded(org.eclipse.uml2.uml.Operation c)
    {
        return Configuration.getBooleanValue("GenerateJavaDoc");
    }     
    
    /**
     * Return true if the user has selected to generate the phpdoc
     * @param c is a property
     * @return a boolean value
     */
    public static boolean isDocNeeded(org.eclipse.uml2.uml.Property c)
    {
        return Configuration.getBooleanValue("GenerateJavaDoc");
    }  
    
    private static void addToTable(String key, String value, String tag)
    {
        if (value == null)
        {
            config.put(key,getDefaultValue(tag));
        }
        else
        {
            config.put(key,value);
        }
    }
    
    /**
     * Load the configuration settings
     */
    private static void initConfig()
    {
        IFile file = GenQos.getModel();

        if (file == null && !parameterized)
        {
        	//if we are here, it means that the uml2qos.LAUNCHER wasn't initialized :(
        	loadDefaultConfig();
        	loadDefaultHeader();
        }
        else if (file != null)
        {
            loadFileConfig(file);
        }
    }

    /**
     * Load the configuration settings from the selected model (in the Package Explorer of Eclipse)
     */
    private static void loadFileConfig(IFile file)
    {
        String s;
	        try
	        {      
	            s = file.getPersistentProperty(new QualifiedName("", "GEN_AUTHOR"));  
	            addToTable("GenerateAuthor",s,"GEN_AUTHOR"); 
	            
	            s = file.getPersistentProperty(new QualifiedName("", "GEN_HEADER"));   
	            addToTable("GenerateHeader",s,"GEN_HEADER");               
	            
	            s = file.getPersistentProperty(new QualifiedName("", "GEN_ACCESSORS"));    
	            addToTable("GenerateAccessors",s,"GEN_ACCESSORS");
	            
	            s = file.getPersistentProperty(new QualifiedName("", "GEN_JAVADOC"));  
	            addToTable("GenerateJavaDoc",s,"GEN_JAVADOC");               
	            
	            s = file.getPersistentProperty(new QualifiedName("", "USE_CHECKSTYLE"));   
	            addToTable("SpacesInsteadOfTab",s,"USE_CHECKSTYLE");
	            
	            s = file.getPersistentProperty(new QualifiedName("", "AUTHOR_NAME"));  
	            addToTable("Author",s,"AUTHOR_NAME");      
	            
	            s = file.getPersistentProperty(new QualifiedName("", "HEADER_TEXT"));   
	            if (s == null)
	            {
	                loadDefaultHeader();
	            }
	            else
	            {
	                header = s;
	            }
            
	        }
	        catch (CoreException e)
	        {
	            Log.log(4,e.toString());
	        }
        }


    /**
     * Set the model file from which to get the configuration parameters. Called by the template file
     * when used directly from an Acceleo chain or reflective editor.
     */
    public void setConfigurationFile(org.eclipse.uml2.uml.Model m, String projectRelativePath)
    {
        IPath projectPath = ResourcesPlugin.getWorkspace().getRoot().getLocation();
        IPath prp = new Path(projectRelativePath);
        IPath path = projectPath.append(prp.removeFirstSegments(1));
        IFile file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(new Path(path.toOSString()));

        if (file != null)
        {
            loadFileConfig(file);
            parameterized = true;
            }
    }
    
}
